package org.zero.onlinesubject.service.impl;

import com.alibaba.fastjson.JSON;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.zero.onlinesubject.entity.Message;
import org.zero.onlinesubject.utils.SessionContext;
import org.zero.onlinesubject.utils.WordUtil;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;

// 这里的ServerEndpoint 就相当于 RequestMapping
@ServerEndpoint("/websocket/{username}/{gid}/{uid}")
@Component
public class WebSocketServer {

    private String username;

    private String uid;

    private String gid;

    private Session session;

    private static ApplicationContext applicationContext;

    public static void setApplicationContext(ApplicationContext context) {
        applicationContext = context;
    }

    // 群发消息
    public void broadcast(Message message){
        String gid = message.getTo();
        List<Session> sessionList = SessionContext.getSessionsByGid(gid);
        if(sessionList.isEmpty()) return;
        message.setText(WordUtil.removeSentiveWords(message.getText()));
        for (Session session : sessionList) {
            try {
                if(session == this.session) continue;

                session.getBasicRemote().sendText(JSON.toJSONString(message));
            } catch (IOException e) {
//                e.printStackTrace();
                System.out.println("异常: "+e.getMessage());
                continue;
                // 如果下面还有需要执行的代码，这里直接停止
            }
        }
    }

    // 建立链接成功调用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "username") String username, @PathParam(value = "gid") String gid, @PathParam(value="uid") String uid){
        // 设置会话空闲过期时间
        this.session = session;
        this.session.setMaxIdleTimeout(3600000);
        this.username = username;
        this.gid = gid;
        this.uid = uid;

        // 将会话信息添加到映射关系中去
        SessionContext.add(uid, this.session);
        SessionContext.addToGroup(uid,gid);

        int num = SessionContext.getOnlineCount(gid);
        String msg = username+"加入webSocket！ 当前人数为: "+num;
        System.out.println(msg);

        // 广播上线消息
        Message message = new Message();
        message.setFrom("System");
        message.setTo(gid);
        message.setText(msg);
        message.setSenddate(LocalDateTime.now());
        broadcast(message);
    }

    // 收到客户端消息后，根据接收的username把消息推下去或者群发
    // 排除法检查该方法可以正常执行
    @OnMessage
    public void onMessage(String message){
        if("ping".equals(message)){
            return;
        }
        Message message1 = JSON.parseObject(message, Message.class);

        broadcast(message1);
    }

    // 错误时调用
    @OnError
    public void onError(Session session,Throwable throwable){
        System.out.println("发送错误!");
        throwable.printStackTrace();
    }

    // 关闭连接时调用
    // 排除法检查该方法可以正常执行
    @OnClose
    public void onClose(){
        SessionContext.remove(uid);
        SessionContext.leaveGroup(uid,gid);

        String msg = username+"离开直播间";
        System.out.println(msg);
        Message message = new Message();
        message.setFrom("System");
        message.setTo(gid);
        message.setText(msg);
        message.setSenddate(LocalDateTime.now());


        broadcast(message);
    }
}
